package com.xiyuan.smartutils.template.engine.expression.operator.comparison;

import com.xiyuan.smartutils.Types;

import com.xiyuan.smartutils.template.engine.VariableMap;
import com.xiyuan.smartutils.template.engine.exception.ExpressionException;
import com.xiyuan.smartutils.template.engine.expression.Expression;
import com.xiyuan.smartutils.template.engine.expression.operator.Operator;

/**
 * 小于比较(<)，对_Lt左右两值进行小于等于比较操作
 * @author lgz 2020年12月7日 新建与整理
 *
 */
public class _LT extends Operator
{
    private static final long serialVersionUID = 1L;
    private Expression left;
    private Expression right;
    
    public _LT(String path, int line, int column, Expression left, Expression right)
    {
        super(path, line, column);
        this.left = left;
        this.right = right;
        this.assertSymbo("小于", left, right);
    }
    
    @Override
    public int getType()
    {
        return LTHEN;
    }
    
    /**
     * 比较大小 只允许数字和字符串 还有就是插入字符
     */
    @Override
    protected Object build(VariableMap variableMap)
    {
        Object prev = left.execute(variableMap);
        Object next = right.execute(variableMap);
        if (prev == null || next == null)
            return false;
        
        if (prev instanceof String || next instanceof String)
        {// 有一个是字符串则认为是字符串相连
            String str1 = String.valueOf(prev);
            String str2 = String.valueOf(next);
            return str1.compareTo(str2) < 0;
        }
        
        if ( (!Types.isNumber(prev) && !Types.isChar(prev)) || (!Types.isNumber(next) && !Types.isChar(next)))
        {// 不是整数和小数
            throw new ExpressionException(this, " < 表达式{" + this + "}，格式不正确，出现值不是数值型和字符串");
        }
        
        if (Types.isInteger(prev))
        {
            if (Types.isInteger(next))
                return ((Number) prev).longValue() < ((Number) next).longValue();
            if (Types.isChar(next))
                return ((Number) prev).longValue() < ((Character) next).charValue();
            else
                return ((Number) prev).longValue() < ((Number) next).doubleValue();
        }
        else if (Types.isDecimal(prev))
        {
            if (Types.isInteger(next))
                return ((Number) prev).doubleValue() < ((Number) next).longValue();
            if (Types.isChar(next))
                return ((Number) prev).doubleValue() < ((Character) next).charValue();
            else
                return ((Number) prev).doubleValue() < ((Number) next).doubleValue();
        }
        else if (Types.isChar(prev))
        {
            if (Types.isInteger(next))
                return ((Character) prev).charValue() < ((Number) next).longValue();
            if (Types.isChar(next))
                return ((Character) prev).charValue() < ((Character) next).charValue();
            else
                return ((Character) prev).charValue() < ((Number) next).doubleValue();
        }
        
        throw new ExpressionException(this, " <= 表达式{" + this + "}，格式不正确，出现值不是数值型和字符串");
    }
    
    @Override
    public String toString()
    {
        return new StringBuilder().append(left).append(" lt ").append(right).toString();
    }
}
